package org.mapdroid.maps.gmaps;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;

import org.mapdroid.MapDroid;
import org.mapdroid.R;
import org.mapdroid.data.adt.Client;
import org.mapdroid.data.adt.MdService;
import org.mapdroid.data.adt.Parking;
import org.mapdroid.login.SettingsActivity;
import org.mapdroid.login.LoginActivity;
import org.mapdroid.maps.gmaps.overlay.MdMarkerItemizedOverlay;
import org.mapdroid.maps.gmaps.overlay.MdMarkerRangeOverlay;
import org.mapdroid.maps.gmaps.overlay.MdMyLocationOverlay;
import org.mapdroid.maps.gmaps.overlay.MdOverlay;
import org.mapdroid.maps.gmaps.overlay.MdRouteOverlay;
import org.mapdroid.search.SearchAddressView;
import org.mapdroid.search.ServiceAddressView;
import org.mapdroid.search.ServiceCategoryView;
import org.mapdroid.search.ServiceNameView;
import org.mapdroid.utils.MdDirectionsActivity;
import org.mapdroid.utils.MdTimer;
import org.mapdroid.data.DataLoader;
import org.xml.sax.SAXException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.content.res.Resources.NotFoundException;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Location;
import android.location.LocationManager;
import android.media.AudioManager;
import android.os.Bundle;
import android.provider.Settings;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.widget.ZoomControls;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class MdMapActivity extends MapActivity implements DialogInterface.OnClickListener, OnClickListener, Runnable{
	public static final int SEARCH_ADDRESS_CONTEXT_CHOICE_ID	= 0;
	public static final int SEARCH_SERVICE_CONTEXT_CHOICE_ID	= 1;
	
	public static final int SEARCH_SERVICE_BY_NAME_CHOICE_ID	= 0;
	public static final int SEARCH_SERVICE_BY_ADDRESS_CHOICE_ID = 1;
	public static final int SEARCH_SERVICE_BY_CATEGORY_CHOICE_ID= 2;
	
	public static final int SEARCH_ADDRESS_INTENT_ID			= 0;
	public static final int SEARCH_SERVICE_NAME_INTENT_ID		= 1;
	public static final int SEARCH_SERVICE_ADDRESS_INTENT_ID	= 2;
	public static final int SEARCH_SERVICE_CATEGORY_INTENT_ID	= 3;
	public static final int SEARCH_PARKING_NAME_INTENT_ID		= 4;
	public static final int SEARCH_PARKING_ADDRESS_INTENT_ID	= 5;
	public static final int SEARCH_PARKING_CATEGORY_INTENT_ID	= 6;
	public static final int LOGIN_INTENT_ID						= 7;
	public static final int PARKING_INTENT_ID					= 8;
	public static final int DIRECTIONS_INTENT_ID				= 9;
	public static final int SERVICE_INTENT_ID 					= 10;
	
	private CharSequence[] viewVector;
	private CharSequence[] searchVector;
	private CharSequence[] searchServiceVector;
	private boolean[]	layerVector;
	
	private MdMapView mapView;
	private AlertDialog.Builder warningDialog, 
								viewModeDialog, 
								searchDialog, 
								searchServiceDialog, 
								errorDialog, 
								yesNoDialog,
								layerDialog;
	
	public static AlertDialog.Builder removeDirectionDialog;
	
	private MdMyLocationOverlay 	mlo;
	private MdMarkerItemizedOverlay parkingOverlay,
									restaurantOverlay,
									beautyCenterOverlay,
									clothingOverlay,
									gymOverlay,
									searchAddressOverlay,
									searchParkingOverlay,
									searchServiceOverlay;
									
	private Hashtable<Integer, Overlay>	removedOverlays;
									
	private MdMarkerRangeOverlay 	rangeOverlay;
	
	private Drawable 	pushPinMarker, 
						parkingMarker,
						parkingNoAvMarker,
						restaurantMarker,
						clothingMarker,
						beautyCenterMarker,
						gymMarker,
						parkingSearchMarker,
						parkingSearchNoAvMarker,
						serviceSearchMarker;
	
	private DataLoader dl;
	public static ArrayList<MdService> serviceList;
	public static ArrayList<Client> usersList;
	public static Client client;
	
	private int viewMode;
	private static float serviceRange;
	public static Location myPosition;
	
	private static Runnable runnable;
	
	private Menu mdActivityMenu;
	private ImageButton trackingButton, layerButton;
	private boolean isMyLocationTracked;
	private ParkingReceiver parkingReceiver;
	
	public static NotificationManager notificationManager;
	
	/****************************************************************
	 *********************ACTIVITY LIFECYCLE*************************
	 ****************************************************************/
	
	@Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.map_view);

        MdMapActivity.runnable = this;
        myPosition = null;
        
        initMap();
        initData();
        initOverlay();
        initApplicationDialog();
	}
	
	@Override
    public void onResume(){
    	super.onResume();
    	Intent newParkingIntent = super.getIntent();
    	Parking park = newParkingIntent.getParcelableExtra(MdMarkerItemizedOverlay.OBJECT);
		if(park!=null){
			updateParkingLayer(park, newParkingIntent);
			notificationManager.cancel(MdTimer.FINISH_NOTIFICATION_ID);
		}
		
    	if(client == null){
			SharedPreferences pref = getApplicationContext().getSharedPreferences(MapDroid.MAPDROID_PREFERENCES, Activity.MODE_APPEND);
    		String username = pref.getString(SettingsActivity.USERNAME, null);
    		if(username!=null){
    			this.setTitle(username + " @ " + getString(R.string.app_name));
    		}
    	}
		
    	else{
    		if(client.getUsername()!=null){
    			this.setTitle(client.getUsername() + " @ " + getString(R.string.app_name));
    			
    			if(mdActivityMenu!=null){
    				if(client.getUsername().length()>2){
    			    	mdActivityMenu.getItem(3).setTitle(R.string.logout_item);
    			    	mdActivityMenu.getItem(3).setIcon(android.R.drawable.ic_lock_power_off);
    			    }
    			    else{
    			    	mdActivityMenu.getItem(3).setTitle(R.string.login_item);
    			    	mdActivityMenu.getItem(3).setIcon(android.R.drawable.ic_lock_lock);
    			    }
    			}
    		}
    	}
    	
    	this.mlo.enableCompass();
		this.mlo.enableMyLocation();
    }
	
    @Override
    public void onPause(){
    	super.onPause();
    	
    	this.mlo.disableMyLocation();
    	this.mlo.disableCompass();
    }

    @Override
    public void onDestroy(){
    	super.onDestroy();
    	this.unregisterReceiver(parkingReceiver);
    }
     
    /**************************************************************
     *********************INITIALIZE METHODS***********************
     **************************************************************/
    
    private boolean isGpsDeviceOn(){
    	String checkGpsDevice = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
        if(checkGpsDevice.length()==0 || checkGpsDevice==null || (!checkGpsDevice.contains(LocationManager.GPS_PROVIDER) && !checkGpsDevice.contains(LocationManager.NETWORK_PROVIDER))){
        	return false;
        }
        return true;
    }
    
    private void initMap(){
    	RelativeLayout relLayout = (RelativeLayout) findViewById(R.id.map_relative_layout);
        
        mapView = new MdMapView(this, this.getResources().getString(R.string.api_key));
        mapView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
        mapView.setClickable(true);
        relLayout.addView(mapView, 0);

        mapView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.fading_in));        
        registerForContextMenu(mapView);

        ZoomControls zoomControls = (ZoomControls)findViewById(R.id.zoom_controls);
        zoomControls.setOnZoomInClickListener( new OnClickListener(){
			@Override
			public void onClick(View arg0) {
				mapView.zoomIn();
			}
        });
        zoomControls.setOnZoomOutClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				mapView.zoomOut();
			}        	
        });
        
        trackingButton = (ImageButton) findViewById(R.id.tracking_my_location_button);
        trackingButton.setOnClickListener(this);
        setIsMyLocationTracked(true);
        
        layerButton = (ImageButton) findViewById(R.id.layer_button);
        layerButton.setOnClickListener(this);
        
        warningDialog = new AlertDialog.Builder(this);
    	warningDialog.setTitle(R.string.warning_dialog_title);
    	warningDialog.setIcon(android.R.drawable.ic_dialog_alert);
        if(!isGpsDeviceOn()){
        	warningDialog.setMessage(this.getString(R.string.gps_off_warning));
        	warningDialog.setNeutralButton(R.string.ok_button_text, this);
        	warningDialog.show();
        }
        
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        
        parkingReceiver = new ParkingReceiver(this);
        parkingReceiver.startReceiver();
    }
    
    private void initData(){
    	try {
			dl = new DataLoader(this);
			client = null;
			
			dl.loadData(R.raw.data);
			serviceList = new ArrayList<MdService>(dl.getDataList());
			
			dl.loadUsers(R.raw.users);
			usersList = new ArrayList<Client>(dl.getUsersList());
		} catch (NotFoundException e) {
			// TODO Auto-generated catch block
			Toast.makeText(this, R.string.file_not_found_error, Toast.LENGTH_SHORT).show();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Toast.makeText(this, R.string.read_file_error, Toast.LENGTH_SHORT).show();
		} 
    }
     
    private void initApplicationDialog(){
    	viewVector = new CharSequence[4];
    	viewVector[MdMapView.MAP_MODE_ID] = getString(R.string.map_item);
    	viewVector[MdMapView.SATELLITE_MODE_ID] = getString(R.string.satellite_item);
    	viewVector[MdMapView.STREET_VIEW_MODE_ID] = getString(R.string.street_view_item);
    	viewVector[MdMapView.TRAFFIC_MODE_ID] = getString(R.string.traffic_item);
    	
    	viewMode = getViewMode(mapView);
    	
    	viewModeDialog = new AlertDialog.Builder(this);
        viewModeDialog.setIcon(android.R.drawable.ic_dialog_map);
        viewModeDialog.setTitle(R.string.title_mode_view);
    	viewModeDialog.setSingleChoiceItems(viewVector, viewMode, this);
    	
    	searchVector = new CharSequence[2];
    	searchVector[MdMapActivity.SEARCH_ADDRESS_CONTEXT_CHOICE_ID] = getString(R.string.search_address_item);
    	searchVector[MdMapActivity.SEARCH_SERVICE_CONTEXT_CHOICE_ID] = getString(R.string.search_service_item);
    	
    	searchDialog = new AlertDialog.Builder(this);
    	searchDialog.setIcon(android.R.drawable.ic_menu_search);
    	searchDialog.setTitle(R.string.search_dialog_title);
		searchDialog.setSingleChoiceItems(searchVector, -1, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				switch(which){
					case MdMapActivity.SEARCH_ADDRESS_CONTEXT_CHOICE_ID:
						Intent searchAddressIntent = new Intent(getBaseContext(), SearchAddressView.class);
		        		startActivityForResult(searchAddressIntent, MdMapActivity.SEARCH_ADDRESS_INTENT_ID);
		        		dialog.cancel();
		        		break;
					case MdMapActivity.SEARCH_SERVICE_CONTEXT_CHOICE_ID:
						dialog.cancel();
						searchServiceDialog.show();
				}
				return;
			}
		});
		
		searchServiceVector = new CharSequence[3];
    	searchServiceVector[MdMapActivity.SEARCH_SERVICE_BY_NAME_CHOICE_ID] = getString(R.string.service_name_search);
    	searchServiceVector[MdMapActivity.SEARCH_SERVICE_BY_ADDRESS_CHOICE_ID] = getString(R.string.service_address_search);
    	searchServiceVector[MdMapActivity.SEARCH_SERVICE_BY_CATEGORY_CHOICE_ID] = getString(R.string.service_category_search);
		
		searchServiceDialog = new AlertDialog.Builder(this);
		searchServiceDialog.setIcon(android.R.drawable.ic_menu_search);
		searchServiceDialog.setTitle(R.string.search_service_dialog_title);
		searchServiceDialog.setSingleChoiceItems(searchServiceVector, -1, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				Intent searchIntent = new Intent();
				searchIntent.putExtra(MdMarkerItemizedOverlay.LIST, serviceList);
				switch(which){
					case MdMapActivity.SEARCH_SERVICE_BY_NAME_CHOICE_ID:
						searchIntent.setClass(getBaseContext(), ServiceNameView.class);
						startActivityForResult(searchIntent, MdMapActivity.SEARCH_SERVICE_NAME_INTENT_ID);
						dialog.cancel();
		        		break;
					case MdMapActivity.SEARCH_SERVICE_BY_ADDRESS_CHOICE_ID:
						searchIntent.setClass(getBaseContext(), ServiceAddressView.class);
						startActivityForResult(searchIntent, MdMapActivity.SEARCH_SERVICE_ADDRESS_INTENT_ID);
						dialog.cancel();
						break;
					case MdMapActivity.SEARCH_SERVICE_BY_CATEGORY_CHOICE_ID:
						searchIntent.setClass(getBaseContext(), ServiceCategoryView.class);
						startActivityForResult(searchIntent, MdMapActivity.SEARCH_SERVICE_CATEGORY_INTENT_ID);
						dialog.cancel();
						break;
				}
				return;
			}
		});
    	
    	errorDialog = new AlertDialog.Builder(this);
    	errorDialog.setTitle(R.string.error_dialog_title);
    	errorDialog.setIcon(android.R.drawable.ic_dialog_alert);
    	errorDialog.setNeutralButton(R.string.ok_button_text, null);
    	
    	yesNoDialog = new AlertDialog.Builder(this);
    	yesNoDialog.setTitle(R.string.yes_no_dialog_title);
    	yesNoDialog.setIcon(android.R.drawable.ic_dialog_alert);
    	yesNoDialog.setNegativeButton(R.string.no_button_text, null);
    	
    	removeDirectionDialog = new AlertDialog.Builder(this);
		removeDirectionDialog.setTitle(R.string.route_dialog_menu_title);
		removeDirectionDialog.setIcon(android.R.drawable.ic_menu_more);
		
		CharSequence[] vector = new CharSequence[1];
		vector[0] = getString(R.string.delete_directions_item);
		removeDirectionDialog.setItems(vector, new DialogInterface.OnClickListener(){

			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				try{
					mapView.getOverlays().remove(MdMapView.DRIVING_DIRECTIONS_OVERLAY_INDEX);
				}catch(IndexOutOfBoundsException e){
					mapView.getOverlays().remove(mapView.getOverlays().size()-1);
    			}catch(Exception e){
    				errorDialog.setMessage(R.string.generic_error);
    				errorDialog.show();
    			}
			}
			
		});
		
		layerVector = new boolean[6];
		removedOverlays = new Hashtable<Integer, Overlay>();
		for(int i=0; i<6; i++){
			layerVector[i]=true;
		}
		
		layerDialog = new AlertDialog.Builder(this);
		layerDialog.setTitle(R.string.layer_dialog_title);
		layerDialog.setMultiChoiceItems(R.array.layer_array, layerVector, new OnMultiChoiceClickListener(){

			@Override
			public void onClick(DialogInterface dialog, int which,
					boolean isChecked) {
				MdOverlay emptyOverlay = new MdOverlay();
				// TODO Auto-generated method stub
				layerVector[which] = isChecked;
				which+=5;
				if(!isChecked){
					switch(which){
						case MdMapView.PARKING_OVERLAY_INDEX:
						case MdMapView.RESTAURANT_OVERLAY_INDEX:
						case MdMapView.BEAUTY_CENTER_OVERLAY_INDEX:
						case MdMapView.CLOTHING_OVERLAY_INDEX:
						case MdMapView.GYM_OVERLAY_INDEX:
							removedOverlays.put(which, mapView.getOverlays().get(which));
							mapView.getOverlays().set(which, emptyOverlay);
						break;
						
						//Search Results
						case 10:
							removedOverlays.put(MdMapView.SEARCH_ADDRESS_OVERLAY_INDEX, mapView.getOverlays().get(MdMapView.SEARCH_ADDRESS_OVERLAY_INDEX));
							removedOverlays.put(MdMapView.SEARCH_PARKING_OVERLAY_INDEX, mapView.getOverlays().get(MdMapView.SEARCH_PARKING_OVERLAY_INDEX));
							removedOverlays.put(MdMapView.SEARCH_SERVICE_OVERLAY_INDEX, mapView.getOverlays().get(MdMapView.SEARCH_SERVICE_OVERLAY_INDEX));
							mapView.getOverlays().set(MdMapView.SEARCH_ADDRESS_OVERLAY_INDEX, emptyOverlay);
							mapView.getOverlays().set(MdMapView.SEARCH_PARKING_OVERLAY_INDEX, emptyOverlay);
							mapView.getOverlays().set(MdMapView.SEARCH_SERVICE_OVERLAY_INDEX, emptyOverlay);
						break;
						
					}
				}
				else{
					switch(which){
						case MdMapView.PARKING_OVERLAY_INDEX:
						case MdMapView.RESTAURANT_OVERLAY_INDEX:
						case MdMapView.BEAUTY_CENTER_OVERLAY_INDEX:
						case MdMapView.CLOTHING_OVERLAY_INDEX:
						case MdMapView.GYM_OVERLAY_INDEX:
							mapView.getOverlays().set(which, removedOverlays.get(which));
						break;
						
						//Search Results
						case 10:
							mapView.getOverlays().set(MdMapView.SEARCH_ADDRESS_OVERLAY_INDEX, removedOverlays.get(MdMapView.SEARCH_ADDRESS_OVERLAY_INDEX));
							mapView.getOverlays().set(MdMapView.SEARCH_PARKING_OVERLAY_INDEX, removedOverlays.get(MdMapView.SEARCH_PARKING_OVERLAY_INDEX));
							mapView.getOverlays().set(MdMapView.SEARCH_SERVICE_OVERLAY_INDEX, removedOverlays.get(MdMapView.SEARCH_SERVICE_OVERLAY_INDEX));
						break;
						
					}
				}
				mapView.postInvalidate();
			}
			
		});
		layerDialog.setPositiveButton(R.string.ok_button_text, null);
    }
    
    private synchronized void initOverlay(){
	    pushPinMarker = getResources().getDrawable(R.drawable.current_position);
		parkingMarker = getResources().getDrawable(R.drawable.parking_av);
		parkingNoAvMarker = getResources().getDrawable(R.drawable.parking_no_av);
		restaurantMarker = getResources().getDrawable(R.drawable.restaurant);
		clothingMarker = getResources().getDrawable(R.drawable.clothing);
		beautyCenterMarker = getResources().getDrawable(R.drawable.beauty_center);
		gymMarker = getResources().getDrawable(R.drawable.gym);
		parkingSearchMarker = getResources().getDrawable(R.drawable.parking_search_av);
		parkingSearchNoAvMarker = getResources().getDrawable(R.drawable.parking_search_no_av);
		serviceSearchMarker = getResources().getDrawable(R.drawable.service_search);

		parkingOverlay = new MdMarkerItemizedOverlay(mapView, this, parkingMarker, MdMapView.PARKING_OVERLAY_INDEX);
	    restaurantOverlay = new MdMarkerItemizedOverlay(mapView, this, restaurantMarker, MdMapView.RESTAURANT_OVERLAY_INDEX);
	    clothingOverlay = new MdMarkerItemizedOverlay(mapView, this, clothingMarker, MdMapView.CLOTHING_OVERLAY_INDEX);
	    beautyCenterOverlay = new MdMarkerItemizedOverlay(mapView, this, beautyCenterMarker, MdMapView.BEAUTY_CENTER_OVERLAY_INDEX);
	    gymOverlay = new MdMarkerItemizedOverlay(mapView, this, gymMarker, MdMapView.GYM_OVERLAY_INDEX);
	    searchAddressOverlay = new MdMarkerItemizedOverlay(mapView, this, pushPinMarker, MdMapView.SEARCH_ADDRESS_OVERLAY_INDEX, serviceList);
	    searchParkingOverlay = new MdMarkerItemizedOverlay(mapView, this, parkingSearchMarker, MdMapView.SEARCH_PARKING_OVERLAY_INDEX);
	    searchServiceOverlay = new MdMarkerItemizedOverlay(mapView, this, serviceSearchMarker, MdMapView.SEARCH_SERVICE_OVERLAY_INDEX);
	    
	    serviceRange = MdMarkerRangeOverlay.DEFAULT_RANGE_E6;
	    rangeOverlay = new MdMarkerRangeOverlay(this, this.mapView, serviceRange);
	    
	    parkingOverlay.addItem(null, new GeoPoint(0, 0), "", "", null);
	    restaurantOverlay.addItem(null, new GeoPoint(0, 0), "", "", null);
	    clothingOverlay.addItem(null, new GeoPoint(0, 0), "", "", null);
	    beautyCenterOverlay.addItem(null, new GeoPoint(0, 0), "", "", null);
	    gymOverlay.addItem(null, new GeoPoint(0, 0), "", "", null);
	    searchAddressOverlay.addItem(null, new GeoPoint(0, 0), "", "", null);
	    searchParkingOverlay.addItem(null, new GeoPoint(0, 0), "", "", null);
	    searchServiceOverlay.addItem(null, new GeoPoint(0, 0), "", "", null);
	    
	    this.mlo = new MdMyLocationOverlay(this, mapView, MdMapActivity.runnable);
	    mapView.getOverlays().add(mlo);

	    addOverlayInList(searchAddressOverlay, MdMapView.SEARCH_ADDRESS_OVERLAY_INDEX);
		addOverlayInList(searchParkingOverlay, MdMapView.SEARCH_PARKING_OVERLAY_INDEX);
		addOverlayInList(searchServiceOverlay, MdMapView.SEARCH_SERVICE_OVERLAY_INDEX);
		
		addOverlayInList(parkingOverlay, MdMapView.PARKING_OVERLAY_INDEX);
		addOverlayInList(restaurantOverlay, MdMapView.RESTAURANT_OVERLAY_INDEX);
		addOverlayInList(beautyCenterOverlay, MdMapView.BEAUTY_CENTER_OVERLAY_INDEX);
		addOverlayInList(clothingOverlay, MdMapView.CLOTHING_OVERLAY_INDEX);
		addOverlayInList(gymOverlay, MdMapView.GYM_OVERLAY_INDEX);
		
		parkingOverlay.removeAllItems();
	    restaurantOverlay.removeAllItems();
	    clothingOverlay.removeAllItems();
	    beautyCenterOverlay.removeAllItems();
	    gymOverlay.removeAllItems();
	    searchAddressOverlay.removeAllItems();
	    searchParkingOverlay.removeAllItems();
	    searchServiceOverlay.removeAllItems();
    }
    
    /**************************************************************
     *************************ACTIVITY MENU************************
     **************************************************************/
	   
    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		this.mdActivityMenu = menu;
	    MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.map_menu, menu);
	    
	    SharedPreferences pref = getApplicationContext().getSharedPreferences(MapDroid.MAPDROID_PREFERENCES, Activity.MODE_APPEND);
		String username = pref.getString(SettingsActivity.USERNAME, " ");
	    if(username.length()>2){
	    	menu.getItem(3).setTitle(R.string.logout_item);
	    	menu.getItem(3).setIcon(android.R.drawable.ic_lock_power_off);
	    }
	    else{
	    	menu.getItem(3).setTitle(R.string.login_item);
	    	menu.getItem(3).setIcon(android.R.drawable.ic_lock_lock);
	    }
	    return true;
	}
    
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){
    	super.onCreateContextMenu(menu, v, menuInfo);
    	menu.setHeaderTitle(R.string.marker_context_menu_title);
    	menu.add(ContextMenu.CATEGORY_CONTAINER, 0, ContextMenu.NONE, R.string.show_indication_item);
    	menu.add(ContextMenu.CATEGORY_CONTAINER, 1, ContextMenu.NONE, R.string.delete_marker_item);
    	menu.add(ContextMenu.CATEGORY_CONTAINER, 2, ContextMenu.NONE, R.string.delete_all_marker_item);
    }
    
    /**************************************************************
     *******************EVENTS HANDLING METHODS********************
     **************************************************************/
    
    @Override
    public boolean onContextItemSelected(MenuItem item) {
    	int markerIndex = mapView.getLastMarkerTapped();
    	final int overlayIndex = mapView.getLastOverlayTapped();
    	final String overlayName = (overlayIndex == MdMapView.SEARCH_ADDRESS_OVERLAY_INDEX) ? 
    									getString(R.string.search_overlay_question) : 
    									getString(R.string.service_overlay_question);
    	
    	switch(item.getItemId()){
    		case 0:
    			startDirectionsActivity(overlayIndex, markerIndex);
    		break;
    			
    		case 1:
    			try{
    				if(overlayIndex == MdMapView.SEARCH_ADDRESS_OVERLAY_INDEX)
    					searchAddressOverlay.removeItem(markerIndex);
    				if(overlayIndex == MdMapView.PARKING_OVERLAY_INDEX)
    					parkingOverlay.removeItem(markerIndex);
    				if(overlayIndex == MdMapView.SEARCH_PARKING_OVERLAY_INDEX)
    					searchParkingOverlay.removeItem(markerIndex);
    				if(overlayIndex == MdMapView.SEARCH_SERVICE_OVERLAY_INDEX)
    					searchServiceOverlay.removeItem(markerIndex);
    				if(overlayIndex == MdMapView.BEAUTY_CENTER_OVERLAY_INDEX)
    					beautyCenterOverlay.removeItem(markerIndex);
    				if(overlayIndex == MdMapView.CLOTHING_OVERLAY_INDEX)
    					clothingOverlay.removeItem(markerIndex);
    				if(overlayIndex == MdMapView.GYM_OVERLAY_INDEX)
    					gymOverlay.removeItem(markerIndex);
    				if(overlayIndex == MdMapView.RESTAURANT_OVERLAY_INDEX)
    					restaurantOverlay.removeItem(markerIndex);
    				
    				mapView.invalidate();
    				Toast.makeText(this, R.string.marker_deleted_notify, Toast.LENGTH_SHORT).show();
    			}catch(Exception e){
    				errorDialog.setMessage(R.string.generic_error);
    				errorDialog.show();
    			}
    			return true;
    			
    		case 2:
    			try{
    				yesNoDialog.setMessage(getString(R.string.delete_all_markers_question) + overlayName);
    				yesNoDialog.setPositiveButton(R.string.yes_button_text, new DialogInterface.OnClickListener(){
    					@Override
						public void onClick(DialogInterface dialog, int which) {
							// TODO Auto-generated method stub
    						if(overlayIndex == MdMapView.SEARCH_ADDRESS_OVERLAY_INDEX)
    							searchAddressOverlay.removeAllItems();
    						if(overlayIndex == MdMapView.SEARCH_PARKING_OVERLAY_INDEX)
    							searchParkingOverlay.removeAllItems();
    						if(overlayIndex == MdMapView.PARKING_OVERLAY_INDEX)
    							parkingOverlay.removeAllItems();
    						if(overlayIndex == MdMapView.SEARCH_SERVICE_OVERLAY_INDEX)
    							searchServiceOverlay.removeAllItems();
    						if(overlayIndex == MdMapView.BEAUTY_CENTER_OVERLAY_INDEX)
    	    					beautyCenterOverlay.removeAllItems();
    	    				if(overlayIndex == MdMapView.CLOTHING_OVERLAY_INDEX)
    	    					clothingOverlay.removeAllItems();
    	    				if(overlayIndex == MdMapView.GYM_OVERLAY_INDEX)
    	    					gymOverlay.removeAllItems();
    	    				if(overlayIndex == MdMapView.RESTAURANT_OVERLAY_INDEX)
    	    					restaurantOverlay.removeAllItems();
    	    				
    						
    						mapView.invalidate();
    						Toast.makeText(getApplicationContext(), R.string.all_marker_deleted_notify, Toast.LENGTH_SHORT).show();
						}
    					
    				});
    				yesNoDialog.show();
    			}
    			catch(Exception e){
    				errorDialog.setMessage(R.string.generic_error);
    				errorDialog.show();
    			}
    			return true;
    	}
    	return super.onContextItemSelected(item);
    }
	
	private void startDirectionsActivity(int overlayIndex, int markerIndex) {
		// TODO Auto-generated method stub
		Location loc = new Location(LocationManager.GPS_PROVIDER);
		Intent directionsIntent = new Intent(this, MdDirectionsActivity.class);
		String text = null;
		if(overlayIndex == MdMapView.SEARCH_ADDRESS_OVERLAY_INDEX){
			double lat = ((Address)searchAddressOverlay.getExtra(markerIndex)).getLatitude();
			double lon = ((Address)searchAddressOverlay.getExtra(markerIndex)).getLongitude();
			loc.setLatitude(lat);
			loc.setLongitude(lon);
			text = searchAddressOverlay.getItem(markerIndex).getTitle();
		}
		if(overlayIndex == MdMapView.PARKING_OVERLAY_INDEX){
			double lat = ((MdService)parkingOverlay.getExtra(markerIndex)).getPosition().getLatitudeE6() / 1E6;
			double lon = ((MdService)parkingOverlay.getExtra(markerIndex)).getPosition().getLongitudeE6() / 1E6;
			loc.setLatitude(lat);
			loc.setLongitude(lon);
			text = parkingOverlay.getItem(markerIndex).getTitle();
		}
		if(overlayIndex == MdMapView.RESTAURANT_OVERLAY_INDEX){
			double lat = ((MdService)restaurantOverlay.getExtra(markerIndex)).getPosition().getLatitudeE6() / 1E6;
			double lon = ((MdService)restaurantOverlay.getExtra(markerIndex)).getPosition().getLongitudeE6() / 1E6;
			loc.setLatitude(lat);
			loc.setLongitude(lon);
			text = restaurantOverlay.getItem(markerIndex).getTitle();
		}
		if(overlayIndex == MdMapView.CLOTHING_OVERLAY_INDEX){
			double lat = ((MdService)clothingOverlay.getExtra(markerIndex)).getPosition().getLatitudeE6() / 1E6;
			double lon = ((MdService)clothingOverlay.getExtra(markerIndex)).getPosition().getLongitudeE6() / 1E6;
			loc.setLatitude(lat);
			loc.setLongitude(lon);
			text = clothingOverlay.getItem(markerIndex).getTitle();
		}
		if(overlayIndex == MdMapView.BEAUTY_CENTER_OVERLAY_INDEX){
			double lat = ((MdService)beautyCenterOverlay.getExtra(markerIndex)).getPosition().getLatitudeE6() / 1E6;
			double lon = ((MdService)beautyCenterOverlay.getExtra(markerIndex)).getPosition().getLongitudeE6() / 1E6;
			loc.setLatitude(lat);
			loc.setLongitude(lon);
			text = beautyCenterOverlay.getItem(markerIndex).getTitle();
		}
		if(overlayIndex == MdMapView.GYM_OVERLAY_INDEX){
			double lat = ((MdService)gymOverlay.getExtra(markerIndex)).getPosition().getLatitudeE6() / 1E6;
			double lon = ((MdService)gymOverlay.getExtra(markerIndex)).getPosition().getLongitudeE6() / 1E6;
			loc.setLatitude(lat);
			loc.setLongitude(lon);
			text = gymOverlay.getItem(markerIndex).getTitle();
		}
		if(overlayIndex == MdMapView.SEARCH_PARKING_OVERLAY_INDEX){
			double lat = ((MdService)searchParkingOverlay.getExtra(markerIndex)).getPosition().getLatitudeE6() / 1E6;
			double lon = ((MdService)searchParkingOverlay.getExtra(markerIndex)).getPosition().getLongitudeE6() / 1E6;
			loc.setLatitude(lat);
			loc.setLongitude(lon);
			text = searchParkingOverlay.getItem(markerIndex).getTitle();
		}
		if(overlayIndex == MdMapView.SEARCH_SERVICE_OVERLAY_INDEX){
			double lat = ((MdService)searchServiceOverlay.getExtra(markerIndex)).getPosition().getLatitudeE6() / 1E6;
			double lon = ((MdService)searchServiceOverlay.getExtra(markerIndex)).getPosition().getLongitudeE6() / 1E6;
			loc.setLatitude(lat);
			loc.setLongitude(lon);
			text = searchServiceOverlay.getItem(markerIndex).getTitle();
		}
		if(myPosition!=null){
			directionsIntent.putExtra(MdDirectionsActivity.START_POINT, myPosition);
			directionsIntent.putExtra(MdDirectionsActivity.START_TEXT, getString(R.string.my_position_text));
			directionsIntent.putExtra(MdDirectionsActivity.END_POINT, loc);
			directionsIntent.putExtra(MdDirectionsActivity.END_TEXT, text);
		}
		
		else{
			directionsIntent.putExtra(MdDirectionsActivity.START_POINT, loc);
			directionsIntent.putExtra(MdDirectionsActivity.START_TEXT, text);
		}
		startActivityForResult(directionsIntent, MdMapActivity.DIRECTIONS_INTENT_ID);
	}

	@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
        	case R.id.mode_item:
        		viewModeDialog.show();
        		return true;
        		
        	case R.id.search_item:
        		searchDialog.show();        				
        		return true;
        	
        	case R.id.log_item:
        		if(item.getTitle().toString().contentEquals(getString(R.string.login_item))){
        			Intent logIntent = new Intent(this, LoginActivity.class);
        			logIntent.putExtra(Client.LIST, usersList);
        			startActivityForResult(logIntent, MdMapActivity.LOGIN_INTENT_ID);
        			return true;
        		}
        		if(item.getTitle().toString().contentEquals(getString(R.string.logout_item))){
        			LoginActivity.logout(getApplicationContext());
        			this.setTitle(R.string.app_name);
        			item.setTitle(R.string.login_item);
        			item.setIcon(android.R.drawable.ic_lock_lock);
        			Toast.makeText(this, R.string.logout_confirmed_notify, Toast.LENGTH_SHORT).show();
        			return true;
        		}
        	break;
        	
        	case R.id.directions_item:
        		int markerIndex = mapView.getLastMarkerTapped();
            	int overlayIndex = mapView.getLastOverlayTapped();
            	
        		startDirectionsActivity(overlayIndex, markerIndex);
        	break;
        }
        return false;
    }
    
	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event){
		// TODO Auto-generated method stub
		super.onKeyDown(keyCode, event);
		switch(keyCode){
			case(KeyEvent.KEYCODE_VOLUME_UP):
				this.setVolumeControlStream(AudioManager.STREAM_SYSTEM);
				mapView.zoomIn();		
				return true;
		
			case(KeyEvent.KEYCODE_VOLUME_DOWN):
				this.setVolumeControlStream(AudioManager.STREAM_SYSTEM);
				mapView.zoomOut();
				return true;
				
			case(KeyEvent.KEYCODE_DPAD_UP):
				mapView.moveUp();
				//KeyEvent.startTracking();
				return true;
				
			case(KeyEvent.KEYCODE_DPAD_DOWN):
				mapView.moveDown();
				//KeyEvent.startTracking();
				return true;
				
			case(KeyEvent.KEYCODE_DPAD_LEFT):
				mapView.moveLeft();
				//KeyEvent.startTracking();
				return true;
				
			case(KeyEvent.KEYCODE_DPAD_RIGHT):
				mapView.moveRight();
				//KeyEvent.startTracking();
				return true;	
				
			case(KeyEvent.KEYCODE_DPAD_CENTER):
				mapView.zoomIn();
				return true;
				
			case(KeyEvent.KEYCODE_SEARCH):
				searchDialog.show();
				return true;
				
		}
		mapView.invalidate();
		return false;
	}
	
	@Override
	public void onClick(DialogInterface dialog, int which) {
		// TODO Auto-generated method stub
		switch(which){
			case AlertDialog.BUTTON_NEUTRAL:
				boolean writedConfig = false;
				
				try{
					writedConfig = Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, LocationManager.GPS_PROVIDER);
				}
				catch(SecurityException e){}
				
				if(writedConfig){
	        		Toast.makeText(this, R.string.gps_on_notify, Toast.LENGTH_SHORT).show();
				}
	        	else{
	            	yesNoDialog.setMessage(this.getString(R.string.gps_on_warning));
	            	yesNoDialog.setPositiveButton(R.string.yes_button_text, this);
	            	yesNoDialog.show();
	        	}
				break;
			
			case AlertDialog.BUTTON_POSITIVE:
				startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
				break;
			
			case MdMapView.MAP_MODE_ID:
				mapView.setSatellite(false);
				dialog.dismiss();
				viewModeDialog.setSingleChoiceItems(viewVector, MdMapView.MAP_MODE_ID, this);
				break;
			case MdMapView.SATELLITE_MODE_ID:
				mapView.setSatellite(true);
				dialog.dismiss();
				viewModeDialog.setSingleChoiceItems(viewVector, MdMapView.SATELLITE_MODE_ID, this);
				break;
			case MdMapView.TRAFFIC_MODE_ID:
				if(mapView.isTraffic())
					mapView.setTraffic(false);
				else
					mapView.setTraffic(true);
				dialog.dismiss();
				viewModeDialog.setSingleChoiceItems(viewVector, MdMapView.TRAFFIC_MODE_ID, this);
				break;
			case MdMapView.STREET_VIEW_MODE_ID:
				if(mapView.isStreetView())
					mapView.setStreetView(false);
				else
					mapView.setStreetView(true);
				dialog.dismiss();
				viewModeDialog.setSingleChoiceItems(viewVector, MdMapView.STREET_VIEW_MODE_ID, this);
				break;
		}
		
	}	
	
	public int getViewMode(MapView map){
		if(map.isSatellite()){
			return MdMapView.SATELLITE_MODE_ID;
		}
		else{
			return MdMapView.TRAFFIC_MODE_ID;
		}
	}
	
	public static synchronized void setServiceRange(float newServiceRange){
		MdMapActivity.serviceRange = newServiceRange;
		Thread t = new Thread(MdMapActivity.runnable);
		t.start();
	}
	
	@Override
	public synchronized void run() {
		// TODO Auto-generated method stub
		//Get the last location acquired by GPS device
		GeoPoint position = mlo.getMyLocation();
		
		if(position == null)
			return; 
		
		myPosition = new Location(LocationManager.GPS_PROVIDER);
		myPosition.setLatitude(position.getLatitudeE6() / 1E6);
		myPosition.setLongitude(position.getLongitudeE6() / 1E6);
		
		if(isMyLocationTracked())
			mapView.getController().animateTo(position);
	
		//RANGE OVERLAY
		rangeOverlay.setPosition(position);
		rangeOverlay.setRange(MdMapActivity.serviceRange);
		rangeOverlay.draw(new Canvas(), this.mapView, true);
		addOverlayInList(rangeOverlay, MdMapView.RANGE_OVERLAY_INDEX);
		
		//SERVICE OVERLAY
		List<MdService> servicePoints = ServiceAddressView.getServiceByPosition(serviceList, position, serviceRange/2);
		if(servicePoints!=null){
			parkingOverlay.removeAllItems();
			restaurantOverlay.removeAllItems();
			beautyCenterOverlay.removeAllItems();
			clothingOverlay.removeAllItems();
			gymOverlay.removeAllItems();
		}
		putServicesOnOverlays(servicePoints);
		
		//...and update the MapView.
		mapView.postInvalidate();
	}
	
	private void putServicesOnOverlays(List<MdService> servicePoints) {
		// TODO Auto-generated method stub
		if(servicePoints == null)
			return;
		
		int size = servicePoints.size();
		
		for(int i=0; i<size; i++){
			MdService tmp = servicePoints.get(i);
			OverlayItem item = new OverlayItem(tmp.getPosition(), tmp.getName(), "");
			switch(tmp.getCategory()){
				case MdService.PARKING:
					parkingOverlay.removeAllItems();
					if(!parkingOverlay.contains(item))
						parkingOverlay.addItem(item, servicePoints.get(i));
				break;
				
				case MdService.RESTAURANT:
					restaurantOverlay.removeAllItems();
					if(!restaurantOverlay.contains(item))
						restaurantOverlay.addItem(item, servicePoints.get(i));
				break;
				
				case MdService.BEAUTY_CENTER:
					beautyCenterOverlay.removeAllItems();
					if(!beautyCenterOverlay.contains(item))
						beautyCenterOverlay.addItem(item, servicePoints.get(i));
				break;
				
				case MdService.CLOTHING:
					clothingOverlay.removeAllItems();
					if(!clothingOverlay.contains(item))
						clothingOverlay.addItem(item, servicePoints.get(i));
				break;
				
				case MdService.GYM:
					gymOverlay.removeAllItems();
					if(!gymOverlay.contains(item))
						gymOverlay.addItem(item, servicePoints.get(i));
				break;

			}
		}
		mapView.postInvalidate();
	}

	private void addOverlayInList(Overlay overlay, int overlayIndex) {
		// TODO Auto-generated method stub
		try{
			if(mapView.getOverlays().contains(overlay))
				mapView.getOverlays().set(overlayIndex, overlay);
			else
				throw new IndexOutOfBoundsException();
		}
		catch(IndexOutOfBoundsException e){
			try{
				mapView.getOverlays().add(overlayIndex, overlay);
			}catch(IndexOutOfBoundsException f){
				mapView.getOverlays().add(overlay);
			}
		}
		mapView.postInvalidate();
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data){
		super.onActivityResult(requestCode, resultCode, data);
		
		switch(requestCode){
			//Change the value of the activity menu after login
			case MdMapActivity.LOGIN_INTENT_ID:
				if(resultCode == Activity.RESULT_OK){
					//Eventuale oggetto da inviare al Parking per la prenotazioe
					client = data.getParcelableExtra(LoginActivity.CLIENT_OBJECT);
					if(client!=null){
						mdActivityMenu.getItem(3).setTitle(R.string.logout_item);
	        			mdActivityMenu.getItem(3).setIcon(android.R.drawable.ic_lock_power_off);
					}
				}
			break;
		
			//View the result of address search
			case MdMapActivity.SEARCH_ADDRESS_INTENT_ID:
				if(resultCode == Activity.RESULT_OK){
					//PUTTING ADDRESS MARKER ON THE MAP
					Address		address = data.getParcelableExtra(SearchAddressView.ADDRESS);
					String 		label	= data.getStringExtra(SearchAddressView.LABEL);
					
					if(address!=null){
						GeoPoint	position= new GeoPoint((int)(address.getLatitude()*1E6), (int)(address.getLongitude()*1E6));
						searchAddressOverlay.addItem(position, label, label, address);
						mapView.getController().animateTo(position);
						return;
					}
					
					//SHOWING SERVICES AROUND THE MARKER
					boolean range = data.getBooleanExtra(MdMarkerItemizedOverlay.RANGE, false);
					Location loc = data.getParcelableExtra(MdMarkerItemizedOverlay.POSITION);
					
					if(range){
						GeoPoint pos = MdMapView.fromLocationToGeoPoint(loc);
						List<MdService> servicePoints = ServiceAddressView.getServiceByPosition(serviceList, pos, MdMarkerRangeOverlay.DEFAULT_RANGE_E6);
						putServicesOnOverlays(servicePoints);
						return;
					}
					
					//SHOWING DIRECTIONS FROM THE MARKER
					Location start = data.getParcelableExtra(MdDirectionsActivity.START_POINT);
					Location end = data.getParcelableExtra(MdDirectionsActivity.END_POINT);
					if(start!=null && end!=null){
						GeoPoint startPoint = MdMapView.fromLocationToGeoPoint(start);
						GeoPoint endPoint = MdMapView.fromLocationToGeoPoint(end);
						showDirections(startPoint, endPoint);
						return;
					}
				}
			break;
			
			case MdMapActivity.SERVICE_INTENT_ID:
				if(resultCode == Activity.RESULT_OK){
					//SHOW PARKING MARKERS AROUND THE SERVICE MARKER
					boolean range = data.getBooleanExtra(MdMarkerItemizedOverlay.RANGE, false);
					if(range){
						Location loc = data.getParcelableExtra(MdMarkerItemizedOverlay.POSITION);
						GeoPoint pos = MdMapView.fromLocationToGeoPoint(loc);

						List<MdService> servicePoints = ServiceAddressView.getServiceByPosition(serviceList, pos, MdMarkerRangeOverlay.DEFAULT_RANGE_E6);
						List<MdService> parkingPoints = new LinkedList<MdService>();
						for(int i=0; i<servicePoints.size(); i++){
							if(servicePoints.get(i).getCategory()==MdService.PARKING)
								parkingPoints.add(servicePoints.get(i));
						}
						
						putServicesOnOverlays(parkingPoints);
					}
					
					//DRIVING DIRECTIONS SHOWN ON THE MAP
					Location start = data.getParcelableExtra(MdDirectionsActivity.START_POINT);
					Location end = data.getParcelableExtra(MdDirectionsActivity.END_POINT);
					if(start!=null && end!=null){
						GeoPoint startPoint = MdMapView.fromLocationToGeoPoint(start);
						GeoPoint endPoint = MdMapView.fromLocationToGeoPoint(end);
						showDirections(startPoint, endPoint);
					}
				}
			break;
			
			case MdMapActivity.SEARCH_SERVICE_ADDRESS_INTENT_ID:
				
			case MdMapActivity.SEARCH_SERVICE_NAME_INTENT_ID:
				
			case MdMapActivity.SEARCH_SERVICE_CATEGORY_INTENT_ID:
				if(resultCode == Activity.RESULT_OK){
					//Showing marker on the map
					MdService service = data.getParcelableExtra(MdMarkerItemizedOverlay.OBJECT);
					GeoPoint pos = service.getPosition();
					String title = service.getName();
					boolean isParking = data.getBooleanExtra(MdMarkerItemizedOverlay.OVERLAY_DATA, false);
					if(isParking){
						searchParkingOverlay.addItem(pos, title, "", service);
						searchParkingOverlay.setClient(client);
						mapView.getController().animateTo(pos);
						
						/*try{
							mapView.getOverlays().set(MdMapView.SEARCH_PARKING_OVERLAY_INDEX, searchParkingOverlay);
						}
						catch(IndexOutOfBoundsException e){
							try{
								mapView.getOverlays().add(MdMapView.SEARCH_PARKING_OVERLAY_INDEX, searchParkingOverlay);
							}catch(IndexOutOfBoundsException f){
								mapView.getOverlays().add(searchParkingOverlay);
							}
						}*/
					}
					else{
						searchServiceOverlay.addItem(pos, title, "", service);
						searchServiceOverlay.setClient(client);
						mapView.getController().animateTo(pos);
						
						/*try{
							mapView.getOverlays().set(MdMapView.SEARCH_SERVICE_OVERLAY_INDEX, searchServiceOverlay);
						}
						catch(IndexOutOfBoundsException e){
							try{
								mapView.getOverlays().add(MdMapView.SEARCH_SERVICE_OVERLAY_INDEX, searchServiceOverlay);
							}catch(IndexOutOfBoundsException f){
								mapView.getOverlays().add(searchServiceOverlay);
							}
						}*/
				
					}
					mapView.postInvalidate();
				}
			break;
			
			//Update parking values after a book
			case MdMapActivity.PARKING_INTENT_ID:
				if(resultCode == Activity.RESULT_OK){
					//Updating parking value
					Parking tmp = data.getParcelableExtra(MdMarkerItemizedOverlay.OBJECT);
					updateParkingLayer(tmp, data);
					break;
				}
			break;
			
			case MdMapActivity.DIRECTIONS_INTENT_ID:
				if(resultCode == Activity.RESULT_OK){
					Location start = data.getParcelableExtra(MdDirectionsActivity.START_POINT);
					Location end = data.getParcelableExtra(MdDirectionsActivity.END_POINT);
					GeoPoint startPoint = MdMapView.fromLocationToGeoPoint(start);
					GeoPoint endPoint = MdMapView.fromLocationToGeoPoint(end);
					showDirections(startPoint, endPoint);
				}
			break;
		}
	}

	private void updateParkingLayer(Parking tmp, Intent data) {
		// TODO Auto-generated method stub
		if(tmp!=null){
			String name = tmp.getName();
			GeoPoint pos = tmp.getPosition();
			int size = serviceList.size();
			for(int i=0; i<size; i++){
				if(serviceList.get(i).getName().contentEquals(name)){
					serviceList.set(i, tmp);
				}
			}
			
			int overlayId = data.getIntExtra(MdMarkerItemizedOverlay.OVERLAY_DATA, -1);
			
			switch(overlayId){
				case MdMapView.PARKING_OVERLAY_INDEX:
					int itemIndex = this.parkingOverlay.contains(pos, name);
					if(itemIndex!=-1){
						if(tmp.getAvailableParkingNumber()!=0)
							parkingOverlay.setItem(itemIndex, pos, name, name, tmp);
						else
							parkingOverlay.setItem(itemIndex, parkingNoAvMarker, pos, name, name, tmp);
					}
					else{
						parkingOverlay.addItem(pos, name, name, tmp);
					}
				break;
				
				case MdMapView.SEARCH_PARKING_OVERLAY_INDEX:
					itemIndex = this.searchParkingOverlay.contains(pos, name);
					if(itemIndex!=-1){
						if(tmp.getAvailableParkingNumber()!=0)
							searchParkingOverlay.setItem(itemIndex, pos, name, name, tmp);
						else
							searchParkingOverlay.setItem(itemIndex, this.parkingSearchNoAvMarker, pos, name, name, tmp);
					}	
					else{
						searchParkingOverlay.addItem(pos, name, name, tmp);
					}
				break;
			}
			mapView.postInvalidate();
		}
		
		//DRIVING DIRECTIONS
		Location start = data.getParcelableExtra(MdDirectionsActivity.START_POINT);
		Location end = data.getParcelableExtra(MdDirectionsActivity.END_POINT);
		if(start!=null && end!=null){
			GeoPoint startPoint = MdMapView.fromLocationToGeoPoint(start);
			GeoPoint endPoint = MdMapView.fromLocationToGeoPoint(end);
			showDirections(startPoint, endPoint);
			
			//addOverlayInList(route, MdMapView.DRIVING_DIRECTIONS_OVERLAY_INDEX);
			//mapView.postInvalidate();
		}
		
		//SHOW PARKING MARKERS AROUND THE SERVICE MARKER
		boolean range = data.getBooleanExtra(MdMarkerItemizedOverlay.RANGE, false);
		if(range){
			Location loc = data.getParcelableExtra(MdMarkerItemizedOverlay.POSITION);
			GeoPoint pos = MdMapView.fromLocationToGeoPoint(loc);
			
			List<MdService> servicePoints = ServiceAddressView.getServiceByPosition(serviceList, pos, MdMarkerRangeOverlay.DEFAULT_RANGE_E6);
			List<MdService> servicePointsWP = new LinkedList<MdService>();
			for(int i=0; i<servicePoints.size(); i++){
				if(servicePoints.get(i).getCategory()!=MdService.PARKING)
					servicePointsWP.add(servicePoints.get(i));
			}
			putServicesOnOverlays(servicePointsWP);
		}
	}

			

	private void showDirections(GeoPoint startPoint, GeoPoint endPoint) {
		// TODO Auto-generated method stub
		MdRouteOverlay route = new MdRouteOverlay(this, mapView, startPoint, endPoint);
		try {
			route.calculatePath();
			route.draw(new Canvas(), mapView, false);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			Toast.makeText(this, "Address Error", Toast.LENGTH_SHORT).show();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Toast.makeText(this, R.string.internet_off, Toast.LENGTH_SHORT).show();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			Toast.makeText(this, "Parser Error", Toast.LENGTH_SHORT).show();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			Toast.makeText(this, "SAX Error", Toast.LENGTH_SHORT).show();
		}
		mapView.animateTo(startPoint);
		/*try{
			mapView.getOverlays().set(MdMapView.DRIVING_DIRECTIONS_OVERLAY_INDEX, route);
		}
		catch(IndexOutOfBoundsException e){
			try{
				mapView.getOverlays().add(MdMapView.DRIVING_DIRECTIONS_OVERLAY_INDEX, route);
			}catch(IndexOutOfBoundsException f){
				mapView.getOverlays().add(route);
			}
		}
		mapView.postInvalidate();*/
		addOverlayInList(route, MdMapView.DRIVING_DIRECTIONS_OVERLAY_INDEX);
	}

	@Override
	public synchronized void onClick(View v) {
		// TODO Auto-generated method stub
		if(v.getId() == R.id.tracking_my_location_button){
			if(isMyLocationTracked){
				((ImageButton)v).setImageResource(R.drawable.b_w_my_position_image);
				setIsMyLocationTracked(false);
				Toast.makeText(this, R.string.tracking_position_disabled_notify, Toast.LENGTH_SHORT).show();
				return;
			}
			else{
				((ImageButton)v).setImageResource(R.drawable.my_position_image);
				setIsMyLocationTracked(true);
				Toast.makeText(this, R.string.tracking_position_enabled_notify, Toast.LENGTH_SHORT).show();
				if(myPosition!=null)
					mapView.animateTo(myPosition);
				return;
			}
		}
		
		if(v.getId() == R.id.layer_button){
			layerDialog.show();
		}
	}
	
	public synchronized boolean isMyLocationTracked(){
		return isMyLocationTracked;
	}
	
	public synchronized void setIsMyLocationTracked(boolean val){
		isMyLocationTracked = val;
	}
	
	/**************************************************************
     *********************BROADCAST RECEIVER***********************
     **************************************************************/
	
	private class ParkingReceiver extends BroadcastReceiver{
		private Context context;

		public ParkingReceiver(Context c){
			super();
			this.context = c;
		}

		public Intent startReceiver(){
			return this.context.registerReceiver((ParkingReceiver)this, new IntentFilter(Intent.ACTION_SEND));
		}
		
		@Override
		public void onReceive(Context context, Intent intent) {
			// TODO Auto-generated method stub
			Intent newParkingIntent = intent;
			Parking park = newParkingIntent.getParcelableExtra(MdMarkerItemizedOverlay.OBJECT);
			if(park!=null){
				updateParkingLayer(park, newParkingIntent);
				notificationManager.cancel(MdTimer.FINISH_NOTIFICATION_ID);
			}
		}
	}
}
